/**
 * @author Zvonimir Pavlic
 */

/**Funkcija za korištenje korisničkog sučelja
 * 
 */
function Glavni(selektor)
{
	var prvi = document.getElementById("prvi");
	var drugi = document.getElementById("drugi");
	var rez = document.getElementById("rez");
	var nul = document.getElementById("nul");
	var labela = document.getElementById("labela");
	var rezultat=0;
	switch (selektor){
		case "0": 
		{
			rezultat = Zbrajaj(prvi.value, drugi.value, nul.value, labela.value);
			break;
		}
		case "1":
		{
			rezultat = Oduzimaj(prvi.value, drugi.value, nul.value, labela.value);
			break;
		}
		case "2":
		{
			rezultat = Mnozi(prvi.value, drugi.value, nul.value, labela.value);
			break;
		}
		case "3":
		{
			rezultat = Dijeli(prvi.value, drugi.value, nul.value, labela.value);
		}
	}
	if (rezultat =="") rezultat = "<e>Bad inputs</e>"; 
	rez.value = rezultat;
}

/**funkcija za zbrajanje pri kojem se čuvaju labele prve matrice
 * 
 * @param {Object} matrica1 matrica kojoj se čuvaju labele
 * @param {Object} matrica2 matrica kojoj se ne čuvaju labele (ona ih nema)
 * @param {Object} r1 broj redaka 1. matrice
 * @param {Object} s1 broj stupaca 2. matrice
 * @param {Object} retci labelirani retci 1. matrice
 * @param {Object} stupci labelirani stupci 1. matrice
 * @param {Object} nul	tretiranje null vrijednosti
 */
function prezervirajLabele(matrica1, matrica2, r1, s1, retci1, stupci1, nul, operacija)
{
	//alert("r1 "+r1+"s1 "+s1 + "retci1 "+retci1 +"stupci1 "+ stupci1);
	var k=0;
	var pribrojnik1=matrica1.toString().split("|");
	var pribrojnik2 = matrica2.toString().split("|");
	var rezultat="";
	var retci = retci1.split(",");
	var stupci = stupci1.split(",");
	var zbroj=0;

	for (var i=0; i< parseInt(r1); i++)
	{
		for (var j=0; j< parseInt(s1); j++)
		{
			//ako se ne radi o labeliranom elementu
			if ((stupci.indexOf(j.toString()) == -1)&&(retci.indexOf(i.toString()) == -1))
			{
				//izračunaj to što trebaš
				switch (operacija) {
					case "+":{
						if ((pribrojnik1[j + i * parseInt(s1)].toString()!="null") && (pribrojnik2[k]!="null"))
						zbroj = parseFloat(pribrojnik1[j + i * parseInt(s1)].toString()) +
						parseFloat(pribrojnik2[k]);
						else if (nul == "null") zbroj="null";
						else if (pribrojnik1[j + i * parseInt(s1)]!="null") zbroj = pribrojnik1[j + i * parseInt(s1)];
						else if (pribrojnik2[k]!= "null") zbroj = pribrojnik2[k];
						break;
					}
					case "-":
					{
						if (pribrojnik1[j + i * parseInt(s1)].toString()!="null" && pribrojnik2[k]!="null")
						zbroj = parseFloat(pribrojnik1[j + i * parseInt(s1)].toString()) -
						parseFloat(pribrojnik2[k]);
						else if (nul = "null") zbroj="null";
						else if (pribrojnik1[j + i * parseInt(s1)]!="null") zbroj = pribrojnik1[j + i * parseInt(s1)];
						else if (pribrojnik2[k]!= "null") zbroj = pribrojnik2[k];
						break;
					}
				}
				if (i==0 && j==0) {
					rezultat += zbroj.toString();
				}
				else 
					rezultat += "|" + zbroj.toString();
				k++;
				
			}
			//ako se radi o labeliranom elementu, samo dodaj labelu u rezultat
			else if (i==0 && j==0) rezultat += pribrojnik1[j + i * parseInt(s1)].toString();
			else rezultat += "|" + pribrojnik1[j + i * parseInt(s1)].toString();
		}
	}
	return rezultat;
}

/**funkcija za zbrajanje pribrojnika  -  matrica, vektora i skalara
 * 
 * @param {Object} prvi 1. pribrojnik
 * @param {Object} drugi 2. pribrojnik
 * @param {Object} nista podatak o tretiranju null vrijednosti: "null" znači da svaka operacija daje "null", 0 znači neutralni element
 * @param {Object} labele oznaka o tretiranju labela-0 -> labele se zanemaruju; 1->čuvaju se labele prve matrice, 2->čuvaju se labele druge matrice, 3-> čuvaju se labele obje matrice
 */
function Zbrajaj(prvi, drugi, nista, labele){
	//izdvajanje specijaln ih oznaka iz elemenata operacije
	//regularni izrazi
	var odvajateljOznake = /<[^>]+>/;
	var odvajateljPodataka = />[^<]+</;
	var eliminatorZagrada = new RegExp('[<,>]', "g");
	
	
	var Prvi = prvi.match(odvajateljPodataka);
	Prvi = new String(Prvi);
	Prvi = Prvi.replace(eliminatorZagrada, '');


	var Drugi = drugi.match(odvajateljPodataka);
	Drugi = new String(Drugi);
	Drugi = Drugi.replace(eliminatorZagrada, '');
	
	
	var oznaka1 = prvi.match(odvajateljOznake);
	var oznaka2 = drugi.match(odvajateljOznake);
	
	
	var pocetnaOznaka1 = oznaka1;
	var pocetnaOznaka2 = oznaka2;
	var rezultat = '';
	
	//interpretacija značenja specijalnih oznaka
	oznaka1 = new String(oznaka1);
	labela1 = oznaka1.match(/;[^>]+>/);
	//alert("l1"+labela1);
	oznaka1 = oznaka1.replace(/;[^>]+>/, ">")
	oznakaKraja = oznaka1.replace(/</, '</');
	oznaka1 = oznaka1.replace(eliminatorZagrada, '');
	oznaka1 = oznaka1.toString().toLowerCase();
	var oz1 = oznaka1.split(/:/);
	var tip1 = oz1[0].toString().match(/[a-z]/);
	oz1[0] = oz1[0].toString().replace(/[a-z]/, '');
	//alert(oz1 + " " + tip1);
	
	var r1 = RetciIzLabele(labela1);
	var s1 = StupciIzLabele(labela1);
	r1 = new String(r1);
	s1 = new String(s1);
	
	var retci1 = r1.split(',');
	var stupci1 = s1.split(',');
	var smanjiRetke1;
	var smanjiStupce1;
	if (r1=='') smanjiRetke1 = 0;
	else smanjiRetke1 = retci1.length;
	if (s1=='') smanjiStupce1 = 0;
	else smanjiStupce1 = stupci1.length;
	
	oznaka2 = new String(oznaka2);
	labela2=oznaka2.match(/;[^>]+>/);
	oznaka2 = oznaka2.toString().toLocaleLowerCase();
	oznaka2 = oznaka2.replace(/;[^>]+>/, ">")
	oznaka2 = oznaka2.replace(eliminatorZagrada,'');
	
	var oz2 = oznaka2.split(/:/);
	var tip2 = oz2[0].toString().match(/[a-z]/);
	oz2[0] = oz2[0].toString().replace(/[a-z]/, '');
	var r2 = RetciIzLabele(labela2);
	var s2 = StupciIzLabele(labela2);
	s2 = new String(s2);
	r2 = new String(r2);
	
	var retci2 = r2.split(',');
	var stupci2 = s2.split(',');
	var smanjiRetke2;
	var smanjiStupce2;
	if (r2=='') smanjiRetke2 = 0;
	else smanjiRetke2 = retci2.length;
	if (s2=='') smanjiStupce2 = 0;
	else smanjiStupce2 = stupci2.length;

	//Izvršavanje operacije zbrajanja
	if (tip1 == 'm' && tip2 == 'm') {
		if (parseInt(oz1[0]) - parseInt(smanjiRetke1) == parseInt(oz2[0]) - parseInt(smanjiRetke2) &&
		parseInt(oz1[1]) - parseInt(smanjiStupce1) == parseInt(oz2[1]) - parseInt(smanjiStupce2)) {
			//alert ("matrice");
			switch (labele) {
				case "0":{
				
					rezultat = "<m" + (parseInt(oz1[0]) - parseInt(smanjiRetke1)).toString() + ":" + (parseInt(oz1[1]) - parseInt(smanjiStupce1)).toString() + ">";//oznakaKraja.replace("</", "<" );
					oznakaKraja = "</m>";

					Prvi = UkloniLabele(Prvi, oz1[0], oz1[1], r1, s1);
					Drugi = UkloniLabele(Drugi, oz2[0], oz2[1], r2, s2);
					
					//alert(Prvi);
					//alert(Drugi);
					//ako se radi o dvije matrice(ili vektora) istih dimenzija
					var pribrojnik1 = Prvi.split('|');
					var pribrojnik2 = Drugi.split('|');
					for (i = 0; i < (parseInt(oz1[0]) - parseInt(smanjiRetke1)) * (parseInt(oz1[1]) - parseInt(smanjiStupce1)); i++) {
						if (pribrojnik1[i] != "null" && pribrojnik2[i] != "null") {
							var zbroj = parseFloat(pribrojnik1[i]) + parseFloat(pribrojnik2[i]);
							if (!i) {
								rezultat += zbroj.toString();
							}
							else 
								rezultat += '|' + zbroj.toString();
						}
						else {
							if (!i) {
								if (nista == "null") 
									rezultat += "null"
								else 
									if (pribrojnik1[i] == "null") {
										if (pribrojnik2[i] == "null") 
											rezultat += "0";
										else 
											rezultat += pribrojnik2[i].toString();
									}
									else 
										rezultat += pribrojnik1[i].toString();
							}
							else 
								if (nista == "null") 
									rezultat += "|null"
								else 
									if (pribrojnik1[i] == "null") {
										if (pribrojnik2[i] == "null") 
											rezultat += '|' + "0";
										else 
											rezultat += '|' + pribrojnik2[i].toString();
									}
									else 
										rezultat += '|' + pribrojnik1[i].toString();
							
						}
					}
					rezultat += oznakaKraja;
					break;
				}
				case "1":
				{
					Drugi = UkloniLabele(Drugi, oz2[0], oz2[1], r2, s2);
					rezultat = pocetnaOznaka1;
					rezultat += prezervirajLabele(Prvi, Drugi, oz1[0], oz1[1], r1, s1, nista,"+");
					rezultat +="</m>";
					break;
					
				}
				case "2":
				{
					Prvi = UkloniLabele(Prvi, oz1[0], oz1[1], r1, s1);
					rezultat = pocetnaOznaka1;
					rezultat += prezervirajLabele(Drugi, Prvi, oz2[0], oz2[1], r2, s2, nista, "+");
					rezultat +="</m>";
					break;
				}
				case "3":
				{
					
				}
			}
		}
			else rezultat ="<e>+: incompatibile matrix dimensions<\e>";
	}
	else 
	if (tip1=='s' && tip2=='s')
	{	
		//ako se radi o dva skalara
		rezultat = "<s>";
		if (Prvi != "null") 
		{
			if (Drugi != "null") 
			{//alert(prvi);
			//alert(drugi);
				rezultat += parseFloat(Prvi) + parseFloat(Drugi);
			}
			else 
			{
				if (nista=="null")
						rezultat += "null"
				else
				rezultat += Prvi;
			}
		}
		else 
		{
			if (Drugi == "null")
				if (nista=="null")
						rezultat += "null"
				else
				rezultat += "0";	
			else 
				if (nista=="null")
						rezultat += "null"
				else
				rezultat += Drugi;						
		}
	rezultat += "</s>";
	}
	else if(tip1=="m" && tip2=="s")
	{
		switch (labele){
			case "2":{}
			case "0":
			{
				var zbroj=0;
				Prvi = UkloniLabele(Prvi, oz1[0], oz1[1], r1, s1);

				rezultat = "<m" + (parseInt(oz1[0]) - parseInt(smanjiRetke1)).toString() + ":" + (parseInt(oz1[1]) - parseInt(smanjiStupce1)).toString() + ">";
				pribrojnik1 = Prvi.toString().split("|");
				
				if (Drugi == "null" && nista != "null") return rezultat + Prvi + "</m>";
				for (i = 0; i < (parseInt(oz1[0]) - parseInt(smanjiRetke1)) * (parseInt(oz1[1]) - parseInt(smanjiStupce1)); i++) 
				{
					if (pribrojnik1[i]!="null" && Drugi!="null")
					{
						zbroj = parseFloat(pribrojnik1[i]) + parseFloat(Drugi);
					}
					else if (nista=="null")
					{
						zbroj = "null";
					}
					else if (pribrojnik1[i]!="null")
					{
						zbroj = pribrojnik1[i];
					}
					else if (Drugi !="null") zbroj = Drugi;
					else zbroj = "null";
					if (!i) rezultat+=zbroj.toString();
					else rezultat += "|"+ zbroj.toString();
				}
				break;
			}
			case "1":
			{
				rezultat = pocetnaOznaka1;
				var zbroj=0;
				pribrojnik1 = Prvi.toString().split("|");
				
				for (var i=0; i< parseInt(oz1[0]); i++)
					for (var j=0; j< parseInt(oz1[1]); j++)
					{
						//ako se ne radi o labeliranom elementu
						if ((stupci1.indexOf(j.toString()) == -1)&&(retci1.indexOf(i.toString()) == -1))
						{
								//izračunaj to što trebaš

							if ((pribrojnik1[j + i * parseInt(oz1[1])].toString()!="null") && (Drugi!="null"))
							zbroj = parseFloat(pribrojnik1[j + i * parseInt(oz1[1])].toString()) +
							parseFloat(Drugi);
							else if (nista == "null") zbroj="null";
							else if (pribrojnik1[j + i * parseInt(oz1[1])]!="null") zbroj = pribrojnik1[j + i * parseInt(oz1[1])];
							else if (Drugi!= "null") zbroj = Drugi;
							if (i==0 && j==0) rezultat += zbroj.toString();
							else rezultat += "|" + zbroj.toString();
						}
					//ako se radi o labeliranom elementu, samo dodaj labelu u rezultat
					else if (i==0 && j==0) rezultat += pribrojnik1[j + i * parseInt(oz1[1])].toString();
					else rezultat += "|" + pribrojnik1[j + i * parseInt(oz1[1])].toString();
					}
			}	
		}
		rezultat += "</m>";
	}
	
	//alert("rezultat:"+ rezultat);
	return rezultat;
}

/**Funkcija za izdvajanje oznaka labeliranih redova
 * 
 * @param {Object} labela popis labeliranih redova i stupaca
 */
function RetciIzLabele(labela)
{
	if (labela == null) return '';
	labela = new String(labela);
	//alert ("labela" +labela);
	
	var retci = new RegExp('[0-9]+r', "g");
	var labeleRedaka = labela.match(retci);
	if (labeleRedaka != null) {	//ako su označeni samo stupci
		var povratak = labeleRedaka.toString();
		povratak = povratak.replace(/r/g, '');
		return povratak;
	}
	return '';
	//alert(povratak);
}

/**Funkcija za izdvajanje oznaka labeliranih stupaca
 * 
 * @param {Object} labela popis labeliranih redova i stupaca
 */
function StupciIzLabele(labela)
{
	if (labela == null) return '';
	labela = new String(labela);
	var retci = new RegExp('[0-9]+s', "g");
	var labeleStupaca = labela.match(retci);
	if (labeleStupaca != null) {	//ako su označeni samo retci
		var povratak = labeleStupaca.toString();
		povratak = povratak.replace(/s/g, '');
		return povratak;
	}
	return '';
}

/**funkcija za uklanjanje labela
 * 
 * @param {Object} podatci matrica podataka iz koje se uklanjaju labele
 * @param {Object} r broj redaka matrice podataka
 * @param {Object} s broj stupaca matrice podataka
 * @param {Object} labeliraniRetci niz sa oznakama labeliranih redova
 * @param {Object} labeliraniStupci niz sa oznakama labeliranih stupaca
 */
function UkloniLabele(podatci, r,s, labeliraniRetci, labeliraniStupci)
{
	//alert("podatci: " + podatci + "   r " + r + "   s "+s+"  lr "+labeliraniRetci+"  ls "+labeliraniStupci);
	labeliraniRetci = labeliraniRetci.toString();
	var retci = labeliraniRetci.split(",");
	labeliraniStupci = labeliraniStupci.toString();
	var stupci = labeliraniStupci.split(",");
	podatci = podatci.toString();
	var podatak = podatci.split("|");
	
	for (var i=0; i<r; i++)
	{
		for(var j=0; j<s; j++)
		{	
			if ((stupci.indexOf(j.toString()) != -1)) {
				podatak[parseInt(j) + (i * (parseInt(s)))] = '';
			}
			if (retci.indexOf(i.toString()) != -1) {
				podatak[parseInt(j) + (i * (parseInt(s)))] = '';
			}
			
			
		}
	}

	//alert(podatci+"    "+podatak);
	var rezultat = podatak.toString();
	rezultat = rezultat.replace(/[,]+/g,"|");
	rezultat = rezultat.replace(/^[|]/, "");
	//alert("rez  "+rezultat);
	return rezultat;
}

 /**funkcija za oduzimanje drugog elementa od prvog elementa, radi s matricama, vektorima i skalarima
  * 
  * @param {Object} prvi element od kojeg se oduzima
  * @param {Object} drugi drugi element kojeg se oduzima
  * @param {Object} nista podatak o tretiranju null vrijednosti: "null" znači da svaka operacija daje "null", 0 znači neutralni element
  * @param {Object} labele tretiranje labela: 0-> labele se uklanjaju, 1 - čuvaju se labele prvog, 2 - čuvaju se labele drugog, 3 - "čuaju" se sve labele
  */
function Oduzimaj(prvi, drugi, nista, labele){
	//izdvajanje specijaln ih oznaka iz elemenata operacije
	//regularni izrazi
	var odvajateljOznake = /<[^>]+>/;
	var odvajateljPodataka = />[^<]+</;
	var eliminatorZagrada = new RegExp('[<,>]', "g");
	
	
	var Prvi = prvi.match(odvajateljPodataka);
	Prvi = new String(Prvi);
	Prvi = Prvi.replace(eliminatorZagrada, '');

	var Drugi = drugi.match(odvajateljPodataka);
	Drugi = new String(Drugi);
	Drugi = Drugi.replace(eliminatorZagrada, '');
	
	
	var oznaka1 = prvi.match(odvajateljOznake);
	var oznaka2 = drugi.match(odvajateljOznake);
	
	
	var pocetnaOznaka1 = oznaka1;
	var pocetnaOznaka2 = oznaka2;
	var rezultat = '';
	
	//interpretacija značenja specijalnih oznaka
	oznaka1 = new String(oznaka1);
	labela1 = oznaka1.match(/;[^>]+>/);
	//alert("l1"+labela1);
	oznaka1 = oznaka1.replace(/;[^>]+>/, ">")
	oznakaKraja = oznaka1.replace(/</, '</');
	oznaka1 = oznaka1.replace(eliminatorZagrada, '');
	oznaka1 = oznaka1.toString().toLowerCase();
	var oz1 = oznaka1.split(/:/);
	var tip1 = oz1[0].toString().match(/[a-z]/);
	oz1[0] = oz1[0].toString().replace(/[a-z]/, '');
	//alert(oz1 + " " + tip1);
	
	var r1 = RetciIzLabele(labela1);
	var s1 = StupciIzLabele(labela1);
	r1 = new String(r1);
	s1 = new String(s1);
	
	var retci1 = r1.split(',');
	var stupci1 = s1.split(',');
	var smanjiRetke1;
	var smanjiStupce1;
	if (r1=='') smanjiRetke1 = 0;
	else smanjiRetke1 = retci1.length;
	if (s1=='') smanjiStupce1 = 0;
	else smanjiStupce1 = stupci1.length;
	
	oznaka2 = new String(oznaka2);
	labela2=oznaka2.match(/;[^>]+>/);
	oznaka2 = oznaka2.toString().toLocaleLowerCase();
	oznaka2 = oznaka2.replace(/;[^>]+>/, ">")
	oznaka2 = oznaka2.replace(eliminatorZagrada,'');
	
	var oz2 = oznaka2.split(/:/);
	var tip2 = oz2[0].toString().match(/[a-z]/);
	oz2[0] = oz2[0].toString().replace(/[a-z]/, '');
	var r2 = RetciIzLabele(labela2);
	var s2 = StupciIzLabele(labela2);
	s2 = new String(s2);
	r2 = new String(r2);
	
	var retci2 = r2.split(',');
	var stupci2 = s2.split(',');
	var smanjiRetke2;
	var smanjiStupce2;
	if (r2=='') smanjiRetke2 = 0;
	else smanjiRetke2 = retci2.length;
	if (s2=='') smanjiStupce2 = 0;
	else smanjiStupce2 = stupci2.length;

	//Izvršavanje operacije zbrajanja
	if (tip1 == 'm' && tip2 == 'm') {
		if (parseInt(oz1[0]) - parseInt(smanjiRetke1) == parseInt(oz2[0]) - parseInt(smanjiRetke2) &&
		parseInt(oz1[1]) - parseInt(smanjiStupce1) == parseInt(oz2[1]) - parseInt(smanjiStupce2)) {
			//alert ("matrice");
			switch (labele) {
				case "0":{
				
					rezultat = "<m" + (parseInt(oz1[0]) - parseInt(smanjiRetke1)).toString() + ":" + (parseInt(oz1[1]) - parseInt(smanjiStupce1)).toString() + ">";//oznakaKraja.replace("</", "<" );
					oznakaKraja = "</m>";
					Prvi = UkloniLabele(Prvi, oz1[0], oz1[1], r1, s1);
					Drugi = UkloniLabele(Drugi, oz2[0], oz2[1], r2, s2);
					
					//alert(Prvi);
					//alert(Drugi);
					//ako se radi o dvije matrice(ili vektora) istih dimenzija
					var pribrojnik1 = Prvi.split('|');
					var pribrojnik2 = Drugi.split('|');
					for (i = 0; i < (parseInt(oz1[0]) - parseInt(smanjiRetke1)) * (parseInt(oz1[1]) - parseInt(smanjiStupce1)); i++) {
						if (pribrojnik1[i] != "null" && pribrojnik2[i] != "null") {
							var zbroj = parseFloat(pribrojnik1[i]) - parseFloat(pribrojnik2[i]);
							//alert(zbroj);
							if (!i) {
								rezultat += zbroj.toString();
							}
							else 
								rezultat += '|' + zbroj.toString();
						}
						else {
							if (!i) {
								if (nista == "null") 
									rezultat += "null"
								else 
									if (pribrojnik1[i] == "null") {
										if (pribrojnik2[i] == "null") 
											rezultat += "0";
										else {
											zbroj = -1* parseFloat(pribrojnik2[i]);
											rezultat += zbroj.toString();
										}
									}
									else 
										rezultat += pribrojnik1[i].toString();
							}
							else 
								if (nista == "null") 
									rezultat += "|null"
								else 
									if (pribrojnik1[i] == "null") {
										if (pribrojnik2[i] == "null") 
											rezultat += '|' + "0";
										else {
											zbroj = -1* parseFloat(pribrojnik2[i]);
											rezultat += '|' + zbroj.toString();
										}
									}
									else 
										rezultat += '|' + pribrojnik1[i].toString();
							
						} //alert(rezultat);
					}
					rezultat += oznakaKraja;
					break;
				}
				case "1":
				{
					Drugi = UkloniLabele(Drugi, oz2[0], oz2[1], r2, s2);
					rezultat = pocetnaOznaka1;
					rezultat += prezervirajLabele(Prvi, Drugi, oz1[0], oz1[1], r1, s1, nista,"-");
					rezultat +="</m>";
					break;
					
				}
				case "2":
				{
					Prvi = UkloniLabele(Prvi, oz1[0], oz1[1], r1, s1);
					rezultat = pocetnaOznaka1;
					rezultat += prezervirajLabele(Drugi, Prvi, oz2[0], oz2[1], r2, s2, nista, "-");
					rezultat +="</m>";
					break;
				}
				case "3":
				{
					
				}
			}
		}
			else rezultat ="<e>+: invalid input parametar dimensions<\e>";
	}
	else 
	if (tip1=='s' && tip2=='s')
	{	
		//ako se radi o dva skalara
		rezultat = "<s>";
		if (Prvi != "null") 
		{
			if (Drugi != "null") 
			{//alert(prvi);
			//alert(drugi);
				rezultat += parseFloat(Prvi) - parseFloat(Drugi);
			}
			else 
			{
				if (nista=="null")
						rezultat += "null"
				else
				rezultat += Prvi;
			}
		}
		else 
		{
			if (Drugi == "null")
				if (nista=="null")
						rezultat += "null"
				else
				rezultat += "0";	
			else 
				if (nista=="null")
						rezultat += "null"
				else
				rezultat += Drugi;						
		}
	rezultat += "</s>";
	}
	else if(tip1=="m" && tip2=="s")
	{
		switch (labele){
			case "2":{}
			case "0":
			{
				var zbroj=0;
				Prvi = UkloniLabele(Prvi, oz1[0], oz1[1], r1, s1);
				rezultat = "<m" + (parseInt(oz1[0]) - parseInt(smanjiRetke1)).toString() + ":" + (parseInt(oz1[1]) - parseInt(smanjiStupce1)).toString() + ">";
				pribrojnik1 = Prvi.toString().split("|")
				
				if (Drugi == "null" && nista != "null") return rezultat + Prvi + "</m>";
				for (i = 0; i < (parseInt(oz1[0]) - parseInt(smanjiRetke1)) * (parseInt(oz1[1]) - parseInt(smanjiStupce1)); i++) 
				{
					if (pribrojnik1[i]!="null" && Drugi!="null")
					{
						zbroj = parseFloat(pribrojnik1[i]) - parseFloat(Drugi);
					}
					else if (nista=="null")
					{
						zbroj = "null";
					}
					else if (pribrojnik1[i]!="null")
					{
						zbroj = pribrojnik1[i];
					}
					else if (Drugi!="null") zbroj = -1* parseFloat(Drugi);
					else zbroj = "null";
					if (!i) rezultat+=zbroj.toString();
					else rezultat += "|"+ zbroj.toString();
				}
				break;
			}
			case "1":
			{
				rezultat = pocetnaOznaka1;
				var zbroj=0;
				pribrojnik1 = Prvi.toString().split("|");
				
				for (var i=0; i< parseInt(oz1[0]); i++)
					for (var j=0; j< parseInt(oz1[1]); j++)
					{
						//ako se ne radi o labeliranom elementu
						if ((stupci1.indexOf(j.toString()) == -1)&&(retci1.indexOf(i.toString()) == -1))
						{
								//izračunaj to što trebaš

							if ((pribrojnik1[j + i * parseInt(oz1[1])].toString()!="null") && (Drugi!="null"))
							zbroj = parseFloat(pribrojnik1[j + i * parseInt(oz1[1])].toString()) -
							parseFloat(Drugi);
							
							else if (pribrojnik1[j + i * parseInt(oz1[1])]!="null") zbroj = pribrojnik1[j + i * parseInt(oz1[1])];
							else if (Drugi!= "null") zbroj = -1 * parseFloat(Drugi);
							else if (nul == "null") zbroj="null";
							if (i==0 && j==0) rezultat += zbroj.toString();
							else rezultat += "|" + zbroj.toString();
						}
					//ako se radi o labeliranom elementu, samo dodaj labelu u rezultat
					else if (i==0 && j==0) rezultat += pribrojnik1[j + i * parseInt(oz1[1])].toString();
					else rezultat += "|" + pribrojnik1[j + i * parseInt(oz1[1])].toString();
					}
			}	
		}
		rezultat += "</m>";
	}
	
	//alert("rezultat:"+ rezultat);
	return rezultat;
}

function Mnozi(prvi, drugi, nista, labele)
{
	//izdvajanje specijaln ih oznaka iz elemenata operacije
	//regularni izrazi
	var odvajateljOznake = /<[^>]+>/;
	var odvajateljPodataka = />[^<]+</;
	var eliminatorZagrada = new RegExp('[<,>]', "g");
	
	
	var Prvi = prvi.match(odvajateljPodataka);
	Prvi = new String(Prvi);
	Prvi = Prvi.replace(eliminatorZagrada, '');

	var Drugi = drugi.match(odvajateljPodataka);
	Drugi = new String(Drugi);
	Drugi = Drugi.replace(eliminatorZagrada, '');
	
	
	var oznaka1 = prvi.match(odvajateljOznake);
	var oznaka2 = drugi.match(odvajateljOznake);
	
	
	var pocetnaOznaka1 = oznaka1;
	var pocetnaOznaka2 = oznaka2;
	var rezultat = '';
	
	//interpretacija značenja specijalnih oznaka
	oznaka1 = new String(oznaka1);
	labela1 = oznaka1.match(/;[^>]+>/);
	//alert("l1"+labela1);
	oznaka1 = oznaka1.replace(/;[^>]+>/, ">")
	oznakaKraja = oznaka1.replace(/</, '</');
	oznaka1 = oznaka1.replace(eliminatorZagrada, '');
	oznaka1 = oznaka1.toString().toLowerCase();
	var oz1 = oznaka1.split(/:/);
	var tip1 = oz1[0].toString().match(/[a-z]/);
	oz1[0] = oz1[0].toString().replace(/[a-z]/, '');
	//alert(oz1 + " " + tip1);
	
	var r1 = RetciIzLabele(labela1);
	var s1 = StupciIzLabele(labela1);
	r1 = new String(r1);
	s1 = new String(s1);
	
	var retci1 = r1.split(',');
	var stupci1 = s1.split(',');
	var smanjiRetke1;
	var smanjiStupce1;
	if (r1=='') smanjiRetke1 = 0;
	else smanjiRetke1 = retci1.length;
	if (s1=='') smanjiStupce1 = 0;
	else smanjiStupce1 = stupci1.length;
	
	oznaka2 = new String(oznaka2);
	labela2=oznaka2.match(/;[^>]+>/);
	oznaka2 = oznaka2.toString().toLocaleLowerCase();
	oznaka2 = oznaka2.replace(/;[^>]+>/, ">")
	oznaka2 = oznaka2.replace(eliminatorZagrada,'');
	
	var oz2 = oznaka2.split(/:/);
	var tip2 = oz2[0].toString().match(/[a-z]/);
	oz2[0] = oz2[0].toString().replace(/[a-z]/, '');
	var r2 = RetciIzLabele(labela2);
	var s2 = StupciIzLabele(labela2);
	s2 = new String(s2);
	r2 = new String(r2);
	
	var retci2 = r2.split(',');
	var stupci2 = s2.split(',');
	var smanjiRetke2;
	var smanjiStupce2;
	if (r2=='') smanjiRetke2 = 0;
	else smanjiRetke2 = retci2.length;
	if (s2=='') smanjiStupce2 = 0;
	else smanjiStupce2 = stupci2.length;
	
		//Obavljanje operacije množenja
	if (tip1=='s' && tip2=='s')
	{

		//množenje dva skalara
		var umnozak;
		if (Prvi!="null" && Drugi!="null" ) 
		var umnozak = parseFloat(Prvi) * parseFloat(Drugi);
		else if (nista == "null")
		umnozak = "null";
		else if (Prvi != "null") umnozak = Prvi;
		else umnozak = Drugi;
		rezultat = '<s>' + umnozak.toString() + '</s>';
		
	}
	
	else if (tip1 == "m" && tip2 == "s")
	{
		switch (labele) {
			case "0":{}
			case "2":
			{
				rezultat = "<m " + (parseInt(oz1[0]) - parseInt(smanjiRetke1)).toString() + ":" + (parseInt(oz1[1]) - parseInt(smanjiStupce1)).toString() + ">";
				Prvi = UkloniLabele(Prvi, oz1[0], oz1[1], r1, s1);
				var faktor1 = Prvi.toString().split("|");
				var umnozak;
				
				if (Drugi == "null" && nista != "null") return rezultat + Prvi + "</m>";
				for (i = 0; i < (parseInt(oz1[0]) - parseInt(smanjiRetke1)) * (parseInt(oz1[1]) - parseInt(smanjiStupce1)); i++)
				{
					
					if (faktor1[i]!="null" && Drugi!="null")
					{
						umnozak = parseFloat(faktor1[i]) * parseFloat(Drugi);
					}
					else if (nista=="null")
					{
						umnozak = "null";
					}
					else if (faktor1[i]!="null")
					{
						umnozak = faktor1[i];
					}
					else if (Drugi !="null")
					umnozak = Drugi;
					else umnozak = "null";
					if (!i) rezultat+=umnozak.toString();
					else rezultat += "|"+ umnozak.toString();
				}
				break;
			}
			case "3":{}
			case "1":
			{
				rezultat = pocetnaOznaka1;
				var umnozak=0;
				var faktor1 = Prvi.toString().split("|");
				
				for (var i=0; i< parseInt(oz1[0]); i++)
					for (var j=0; j< parseInt(oz1[1]); j++)
					{
						//ako se ne radi o labeliranom elementu
						if ((stupci1.indexOf(j.toString()) == -1)&&(retci1.indexOf(i.toString()) == -1))
						{
								//izračunaj to što trebaš

							if ((faktor1[j + i * parseInt(oz1[1])].toString()!="null") && (Drugi!="null"))
							umnozak = parseFloat(faktor1[j + i * parseInt(oz1[1])].toString()) *
							parseFloat(Drugi);
							else if (nista == "null") umnozak="null";
							else if (faktor1[j + i * parseInt(oz1[1])]!="null") umnozak = faktor1[j + i * parseInt(oz1[1])];
							else if (Drugi!= "null") umnozak = Drugi;
							if (i==0 && j==0) rezultat += umnozak.toString();
							else rezultat += "|" + umnozak.toString();
						}
					//ako se radi o labeliranom elementu, samo dodaj labelu u rezultat
					else if (i == 0 && j == 0) {
						var t=j + i * parseInt(oz1[1]);

						rezultat += faktor1[j + i * parseInt(oz1[1])].toString();
					}
					else 
						rezultat += "|" + faktor1[j + i * parseInt(oz1[1])].toString();
					}
				break;
			}
		}
		rezultat += "</m>";
	}
	else rezultat = "<e>Multiply: bad inputs</e>"
	return rezultat;
}

function Dijeli(djeljenik, djelitelj, nista, labele)
{
	var odvajateljOznake = /<[^>]+>/;
	var odvajateljPodataka = />[^<]+</;
	var eliminatorZagrada = new RegExp('[<,>]',"g");
	
	var oznaka = djelitelj.match(odvajateljOznake);

	//interpretacija značenja specijalnih oznaka
	oznaka = new String(oznaka);
	oznakaKraja = oznaka.replace(/</,'</');
	var noviDjeljitelj = oznaka;
	oznaka = oznaka.replace(eliminatorZagrada,'');
	var oz = oznaka.split(/:/);
	var tip = oz[0].toString().match(/[a-z]/);
	
	//ako je definirano dijeljenje skalarom, onda dijeli
	if (tip=="s")
	{
		var prvi = djelitelj.match(odvajateljPodataka);
		prvi = new String(prvi);
		prvi = prvi.replace(eliminatorZagrada, '');
		
		if (prvi == "0")
			return "<e>/: division by zero</e>"
		else if (prvi == "null")
		return Mnozi(djeljenik, djelitelj, nista, labele);
		else
		{	
			var novi = parseFloat(prvi);
			var pravi = 1/prvi;

			var noviDjeljitelj ="<s>" + pravi.toString() + "</s>";
			return Mnozi(djeljenik, noviDjeljitelj, nista, labele);
		}
		
	}
	else return "<e>/:undefined division operation</e>"	
}


